package com.mxchip.livestar.ui.call

import android.app.Application
import android.os.Looper
import androidx.lifecycle.*
import androidx.lifecycle.Observer
import com.mxchip.livestar.repository.RoomClientRepository
import com.mxchip.livestar.utils.FileLog
import com.mxchip.livestar.utils.MyLog
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.subjects.PublishSubject
import java.text.SimpleDateFormat
import java.util.*


/**
 * pass信令 数据管理类
 */
class DbyViewModel(application: Application) : AndroidViewModel(application) {

    private val logger: FileLog = FileLog.getLogger(DbyViewModel::class.java)

    private val avRepository = AVRepository


    private val _videoResInitFinish = MutableLiveData<Boolean>(false)

    val videoResInitFinish: LiveData<Boolean>
        get() = _videoResInitFinish

    /**
     * 视频相关资源初始化完成
     */
    fun videoResInitFinish(value: Boolean) {
        _videoResInitFinish.postValue(value)
    }


    private val _camera = MutableLiveData<Boolean>(false)

    val camera: LiveData<Boolean>
        get() = _camera

    /**
     * 开关摄像头
     */
    fun camera(value: Boolean) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            _camera.value = value
        } else {
            _camera.postValue(value)
        }
    }


    private val _mic by lazy { MutableLiveData<Boolean>(false) }

    val mic: LiveData<Boolean>
        get() = _mic

    /**
     * 开关mic
     */
    fun mic(value: Boolean) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            _mic.value = value
        } else {
            _mic.postValue(value)
        }
    }


    var extMicType = MediatorLiveData<Int>().apply {
        value = AVDevice.NONE_RES
    }

    private var extMicObserver = Observer<Any> {
        extMicType.value = if (openExtMic.value!!) shareScreen.value!! else AVDevice.NONE_RES
    }


    val openExtMic = avRepository.openExtMic

    /**
     * 共享屏幕是否开启mic
     */
    fun extMic(value: Boolean) {
        avRepository.extMic(value)
    }

    /**
     * 共享屏幕
     */
    fun resShareResponse(value: Boolean) {
        avRepository.resShareResponse(value)
    }

    private val _hdmi: MutableLiveData<Boolean> = MutableLiveData(false)

    val hdmi: LiveData<Boolean>
        get() = _hdmi

    /**
     * 开启hdmi
     */
    fun hdmi(value: Boolean) {
        MyLog.logD(MyLog.HDMI_CAMERA_SEND_MODEL,"DbyViewModel::hdmi: value:${value}  ")
        if (Looper.myLooper() == Looper.getMainLooper()) {
            _hdmi.value = value
        } else {
            _hdmi.postValue(value)
        }
    }


    private val _share_screen = MediatorLiveData<Int>().apply {
        value = AVDevice.NONE_RES
    }

    val shareScreen: MutableLiveData<Int>
        get() = _share_screen

    private val shareScreenObserver = Observer<Any> {
        if (_showHDMIView.value!!) {
            _share_screen.value = AVDevice.HDMI_RES
        } else if (_showWiFiView.value!!) {
            _share_screen.value = AVDevice.WIFI_RES
        } else if (!_showHDMIView.value!! && !_showWiFiView.value!!) {
            _share_screen.value = AVDevice.NONE_RES
        }
    }


    private val _showHDMIView: MutableLiveData<Boolean> = MutableLiveData(false)

    val showHDMIView: LiveData<Boolean>
        get() = _showHDMIView

    /**
     * 展示hdmi的画面
     */
    fun showHDMIView(value: Boolean) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            _showHDMIView.value = value
        } else {
            _showHDMIView.postValue(value)
        }
    }

    private val _showWiFiView: MutableLiveData<Boolean> = MutableLiveData(false)

    val showWiFiView: LiveData<Boolean>
        get() = _showWiFiView

    /**
     * 展示无线投屏的画面
     */
    fun showWiFiView(value: Boolean) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            _showWiFiView.value = value
        } else {
            _showWiFiView.postValue(value)
        }
    }

    init {
        _share_screen.addSource(_showHDMIView, shareScreenObserver)
        _share_screen.addSource(_showWiFiView, shareScreenObserver)

        extMicType.addSource(openExtMic, extMicObserver)
        extMicType.addSource(_share_screen, extMicObserver)
    }

    private val _showRemoteResView: MutableLiveData<Boolean> = MutableLiveData(false)

    val showRemoteResView: LiveData<Boolean>
        get() = _showRemoteResView

    fun showRemoteResView(value: Boolean) {
        _showRemoteResView.value = value
    }

    private val compositeDisposable: CompositeDisposable by lazy {
        CompositeDisposable()
    }

    /*private val sendAVPacketSubject: PublishSubject<AVPacket> by lazy {
        PublishSubject.create<AVPacket>()
    }*/

    /*private val receiveAVPacketSubject: PublishSubject<AVPacket> by lazy {
        PublishSubject.create<AVPacket>()
    }*/
    /*private val sendAudioPacketSubject: PublishSubject<AVPacket> by lazy {
        PublishSubject.create<AVPacket>()
    }*/


    private val roomId = MutableLiveData<String?>()

    // val avDevices = RoomClientRepository.avDevices
    // val mIsEnter = AVRepository.mIsEnter

    override fun onCleared() {
        compositeDisposable.clear()
        avRepository.clear()
    }

    fun join(): LiveData<String?> {
        return roomId
    }

    fun join(id: String?) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            roomId.value = id
        } else {
            roomId.postValue(id)
        }
    }

    private val _netQuality: MutableLiveData<String> = MutableLiveData()

    val netQuality: LiveData<String>
        get() = _netQuality

    /**
     * 网络质量回调
     */
    fun netQuality(value: String) {
        _netQuality.postValue(value)
    }

    //-------------------------video-----------------------------
    /**
     * 发送视频数据-下游
     */
    /*fun sendAVPacketConsumer(consumer: Consumer<AVPacket>): Disposable {
        val disposable = sendAVPacketSubject.subscribe(consumer)
        compositeDisposable.add(disposable)
        return disposable
    }*/

    /**
     * 发送视频数据-上游
     */
    /*fun sendAVPacket(avPacket: AVPacket) {
        sendAVPacketSubject.onNext(avPacket)
    }*/

    /**
     * 收视频数据-下游
     */
    /*fun receiveAVPacketConsumer(consumer: Consumer<AVPacket>): Disposable {
        val disposable = receiveAVPacketSubject.subscribe(consumer, Consumer<Any> {
            run {
                logger.error(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(Date()) +
                        " receiveAVPacketConsumer" + it)
            }
        })
        compositeDisposable.add(disposable)
        return disposable
    }*/

    /**
     * 收视频数据-上游
     */
    /*fun receiveAVPacket(avPacket: AVPacket) {
        receiveAVPacketSubject.onNext(avPacket)
    }*/

    //-------------------------audio-----------------------------
    /*fun sendAudioPacketConsumer(consumer: Consumer<AVPacket>): Disposable {
        val disposable = sendAudioPacketSubject.subscribe(consumer)
        compositeDisposable.add(disposable)
        return disposable
    }

    fun sendAudioPacket(avPacket: AVPacket) {
        sendAudioPacketSubject.onNext(avPacket)
    }*/

}

/**
 * 设备实体类
 */
object AVDevice {
    const val CAMERA_LOCAL = "frontCameraHD"
    const val CAMERA_LOCAL_SMALL = ""
    const val CAMERA_HDMI = "hdmi"
    const val CAMERA_WIFI = "cameraWifi"
    const val AUDIO_BUILD_IN = "audioBuildIn"
    const val HDMI_RES = 1
    const val WIFI_RES = 2
    const val NONE_RES = -1
}

/**
 * 数据包实体类
 */
data class AVPacket @JvmOverloads constructor(val data: ByteArray, val deviceName: String, val uid: String, val format: Int = 0, val width: Int = 0, val height: Int = 0, val rotation: Int = 0, val timestamp: Long = 0) {

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as AVPacket

        if (!data.contentEquals(other.data)) return false
        if (deviceName != other.deviceName) return false
        if (uid != other.uid) return false
        if (format != other.format) return false
        if (width != other.width) return false
        if (height != other.height) return false
        if (rotation != other.rotation) return false
        if (timestamp != other.timestamp) return false

        return true
    }

    override fun hashCode(): Int {
        var result = data.contentHashCode()
        result = 31 * result + deviceName.hashCode()
        result = 31 * result + uid.hashCode()
        result = 31 * result + format
        result = 31 * result + width
        result = 31 * result + height
        result = 31 * result + rotation
        result = 31 * result + timestamp.hashCode()
        return result
    }

}